<template>
	<div class="audio-recorder">
		<div class="recorder-title">录音控制</div>
		
		<!-- 录音状态显示 -->
		<div class="recorder-status">
			<div class="status-indicator" :class="statusClass">
				{{ statusText }}
			</div>
			<div v-if="isRecording" class="recording-time">
				录音时长: {{ formatTime(recordingTime) }}
			</div>
		</div>
		
		<!-- 录音控制按钮 -->
		<div class="recorder-controls">
			<van-button 
				@click="startRecording" 
				:disabled="!canStart"
				type="primary"
				
			>
				开始录音
			</van-button>
			
			<van-button 
				@click="pauseRecording" 
				:disabled="!canPause"
				type="warning"
				
			>
				{{ isPaused ? '继续录音' : '暂停录音' }}
			</van-button>
			
			<van-button 
				@click="stopRecording" 
				:disabled="!canStop"
				type="danger"
				
			>
				结束录音
			</van-button>
			
			<van-button 
				@click="testMicrophone" 
				type="default"
				
			>
				测试麦克风
			</van-button>
		</div>
		
		<!-- 录音文件信息 -->
		<div v-if="recordingPath" class="recording-info">
			<div class="file-info">
				<span>录音文件: {{ getFileName(recordingPath) }}</span>
			</div>
			<div class="file-actions">
				<van-button @click="playRecording" type="primary">播放录音</van-button>
				<van-button @click="saveRecording" type="primary">保存录音</van-button>
				<van-button @click="deleteRecording" type="primary">删除录音</van-button>
			</div>
		</div>
		
		<!-- 录音播放器 -->
		<div v-if="isPlayingRecording" class="recording-player">
			<div class="player-info">
				正在播放录音...
			</div>
			<van-button @click="stopPlayingRecording" type="danger">
				停止播放
			</van-button>
		</div>
		
		<!-- 平台兼容性提示 -->
		<div v-if="!isSupported" class="compatibility-warning">
			<span>当前平台不支持录音功能</span>
		</div>
	</div>
</template>

<script setup>
import { ref, computed, onMounted, onBeforeUnmount } from 'vue'

// 响应式数据
// 录音状态
const isRecording = ref(false)
const isPaused = ref(false)
const isPlayingRecording = ref(false)

// 录音管理器
const recorderManager = ref(null)

// 录音时间
const recordingTime = ref(0)
const recordingTimer = ref(null)

// 录音文件路径
const recordingPath = ref('')

// 播放器
const audioContext = ref(null)

// 初始化状态
const isInitialized = ref(false)
const isSupported = ref(true)

// H5录音相关
const mediaRecorder = ref(null)
const audioChunks = ref([])
const stream = ref(null)
const analyser = ref(null)
const microphone = ref(null)

// 计算属性
// 状态文本
const statusText = computed(() => {
	if (!isSupported.value) {
		return '不支持录音'
	} else if (!isInitialized.value) {
		return '初始化中...'
	} else if (isRecording.value && !isPaused.value) {
		return '正在录音...'
	} else if (isRecording.value && isPaused.value) {
		return '录音已暂停'
	} else if (recordingPath.value) {
		return '录音完成'
	} else {
		return '准备录音'
	}
})

// 状态样式类
const statusClass = computed(() => {
	if (!isSupported.value) {
		return 'unsupported'
	} else if (!isInitialized.value) {
		return 'initializing'
	} else if (isRecording.value && !isPaused.value) {
		return 'recording'
	} else if (isRecording.value && isPaused.value) {
		return 'paused'
	} else if (recordingPath.value) {
		return 'completed'
	} else {
		return 'ready'
	}
})

// 按钮状态
const canStart = computed(() => {
	return isSupported.value && isInitialized.value && !isRecording.value && !recordingPath.value
})

const canPause = computed(() => {
	return isSupported.value && isInitialized.value && isRecording.value
})

const canStop = computed(() => {
	return isSupported.value && isInitialized.value && isRecording.value
})

onMounted(() => {
	initRecorder()
})

onBeforeUnmount(() => {
	cleanup()
})

// 方法函数
// 初始化录音管理器
const initRecorder = () => {
	try {
		// H5环境使用Web Audio API
		setupWebRecorder()
		
	} catch (error) {
		console.error('录音管理器初始化失败:', error)
		isSupported.value = false
	}
}

// 设置Web录音管理器
const setupWebRecorder = async () => {
	// 检查浏览器支持
	if (!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia) {
		console.error('浏览器不支持录音功能')
		isSupported.value = false
		alert('浏览器不支持录音功能')
		return
	}
	
	// 检查MediaRecorder支持
	if (!window.MediaRecorder) {
		console.error('浏览器不支持MediaRecorder')
		isSupported.value = false
		alert('浏览器不支持录音功能')
		return
	}
	
	// 检查音频设备
	try {
		const devices = await navigator.mediaDevices.enumerateDevices()
		const audioInputs = devices.filter(device => device.kind === 'audioinput')
		
		if (audioInputs.length === 0) {
			console.warn('未检测到麦克风设备')
			// 不阻止初始化，让用户尝试录音时再处理
		} else {
			console.log('检测到音频输入设备:', audioInputs.length, '个')
		}
	} catch (error) {
		console.warn('无法枚举设备:', error)
	}
	
	isInitialized.value = true
	isSupported.value = true
	console.log('Web录音初始化成功')
}

// 设置H5录音
const setupH5Recorder = () => {
	// 检查浏览器支持
	if (!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia) {
		console.error('浏览器不支持录音功能')
		isSupported.value = false
		uni.showToast({
			title: '浏览器不支持录音功能',
			icon: 'none'
		})
		return
	}
	
	// 检查MediaRecorder支持
	if (!window.MediaRecorder) {
		console.error('浏览器不支持MediaRecorder')
		isSupported.value = false
		uni.showToast({
			title: '浏览器不支持录音功能',
			icon: 'none'
		})
		return
	}
	
	isInitialized.value = true
	isSupported.value = true
	console.log('H5录音初始化成功')
}

// 开始录音
const startRecording = () => {
	if (!isSupported.value || !isInitialized.value) {
		alert('录音功能未就绪')
		return
	}
	
	startWebRecording()
}

// Web录音开始
const startWebRecording = async () => {
	try {
		// 首先检查可用的音频设备
		const devices = await navigator.mediaDevices.enumerateDevices()
		const audioInputs = devices.filter(device => device.kind === 'audioinput')
		
		if (audioInputs.length === 0) {
			throw new Error('未检测到麦克风设备，请检查设备连接')
		}
		
		console.log('检测到的音频输入设备:', audioInputs)
		
		// 请求麦克风权限，使用更宽松的配置
		stream.value = await navigator.mediaDevices.getUserMedia({
			audio: {
				echoCancellation: false,
				noiseSuppression: false,
				autoGainControl: false,
				sampleRate: 44100,
				channelCount: 1
			}
		})
		
		// 创建MediaRecorder
		mediaRecorder.value = new MediaRecorder(stream.value, {
			mimeType: 'audio/webm;codecs=opus'
		})
		
		// 重置音频块
		audioChunks.value = []
		
		// 录音数据事件
		mediaRecorder.value.ondataavailable = (event) => {
			if (event.data.size > 0) {
				audioChunks.value.push(event.data)
			}
		}
		
		// 录音停止事件
		mediaRecorder.value.onstop = () => {
			const audioBlob = new Blob(audioChunks.value, { type: 'audio/webm' })
			recordingPath.value = URL.createObjectURL(audioBlob)
			isRecording.value = false
			isPaused.value = false
			stopTimer()
			
			alert('录音完成')
		}
		
		// 录音错误事件
		mediaRecorder.value.onerror = (event) => {
			console.error('录音错误:', event.error)
			alert('录音失败')
			resetRecording()
		}
		
		// 开始录音
		mediaRecorder.value.start(1000) // 每秒收集一次数据
		isRecording.value = true
		isPaused.value = false
		startTimer()
		
		console.log('Web录音开始')
		
	} catch (error) {
		console.error('Web录音启动失败:', error)
		
		// 提供更详细的错误信息
		let errorMessage = '录音启动失败: '
		if (error.name === 'NotAllowedError') {
			errorMessage += '麦克风权限被拒绝，请在浏览器设置中允许麦克风访问'
		} else if (error.name === 'NotFoundError') {
			errorMessage += '未找到麦克风设备，请检查设备连接'
		} else if (error.name === 'NotReadableError') {
			errorMessage += '麦克风被其他应用占用，请关闭其他录音应用'
		} else if (error.name === 'OverconstrainedError') {
			errorMessage += '麦克风配置不支持，尝试使用默认设置'
		} else {
			errorMessage += error.message
		}
		
		alert(errorMessage)
		
		// 尝试使用更简单的配置作为备用方案
		try {
			console.log('尝试使用备用录音配置...')
			stream.value = await navigator.mediaDevices.getUserMedia({
				audio: true
			})
			
			mediaRecorder.value = new MediaRecorder(stream.value)
			
			// 重置音频块
			audioChunks.value = []
			
			// 录音数据事件
			mediaRecorder.value.ondataavailable = (event) => {
				if (event.data.size > 0) {
					audioChunks.value.push(event.data)
				}
			}
			
			// 录音停止事件
			mediaRecorder.value.onstop = () => {
				const audioBlob = new Blob(audioChunks.value, { type: 'audio/webm' })
				recordingPath.value = URL.createObjectURL(audioBlob)
				isRecording.value = false
				isPaused.value = false
				stopTimer()
				
				alert('录音完成（使用备用配置）')
			}
			
			// 录音错误事件
			mediaRecorder.value.onerror = (event) => {
				console.error('备用录音错误:', event.error)
				alert('备用录音失败')
				resetRecording()
			}
			
			// 开始录音
			mediaRecorder.value.start(1000)
			isRecording.value = true
			isPaused.value = false
			startTimer()
			
			console.log('备用录音配置启动成功')
			
		} catch (fallbackError) {
			console.error('备用录音配置也失败:', fallbackError)
			alert('所有录音配置都失败，请检查设备权限')
		}
	}
}

// 暂停录音
const pauseRecording = () => {
	if (!isSupported.value || !isInitialized.value) {
		alert('录音功能不可用')
		return
	}
	
	if (mediaRecorder.value) {
		try {
			if (isPaused.value) {
				mediaRecorder.value.resume()
				isPaused.value = false
				startTimer()
			} else {
				mediaRecorder.value.pause()
				isPaused.value = true
				stopTimer()
			}
		} catch (error) {
			console.error('暂停/继续录音失败:', error)
			alert('操作失败')
		}
	}
}

// 停止录音
const stopRecording = () => {
	if (!isSupported.value || !isInitialized.value) {
		alert('录音功能不可用')
		return
	}
	
	if (mediaRecorder.value) {
		try {
			mediaRecorder.value.stop()
			// 停止媒体流
			if (stream.value) {
				stream.value.getTracks().forEach(track => track.stop())
			}
		} catch (error) {
			console.error('停止录音失败:', error)
			alert('停止录音失败')
		}
	}
}

// 开始计时
const startTimer = () => {
	recordingTimer.value = setInterval(() => {
		recordingTime.value += 1
	}, 1000)
}

// 停止计时
const stopTimer = () => {
	if (recordingTimer.value) {
		clearInterval(recordingTimer.value)
		recordingTimer.value = null
	}
}

// 格式化时间
const formatTime = (seconds) => {
	const mins = Math.floor(seconds / 60)
	const secs = seconds % 60
	return `${mins.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`
}

// 获取文件名
const getFileName = (path) => {
	return path.split('/').pop() || '未知文件'
}

// 重置录音状态
const resetRecording = () => {
	isRecording.value = false
	isPaused.value = false
	recordingTime.value = 0
	recordingPath.value = ''
	stopTimer()
}

// 测试麦克风
const testMicrophone = async () => {
	try {
		alert('正在测试麦克风权限...')
		
		// 检查设备
		const devices = await navigator.mediaDevices.enumerateDevices()
		const audioInputs = devices.filter(device => device.kind === 'audioinput')
		
		if (audioInputs.length === 0) {
			alert('❌ 未检测到麦克风设备\n\n请检查：\n1. 麦克风是否正确连接\n2. 设备驱动是否正常\n3. 浏览器是否支持音频输入')
			return
		}
		
		console.log('检测到的音频设备:', audioInputs)
		
		// 测试权限
		const testStream = await navigator.mediaDevices.getUserMedia({
			audio: {
				echoCancellation: false,
				noiseSuppression: false,
				autoGainControl: false
			}
		})
		
		// 创建音频上下文进行测试
		const testAudioContext = new (window.AudioContext || window.webkitAudioContext)()
		const analyser = testAudioContext.createAnalyser()
		const microphone = testAudioContext.createMediaStreamSource(testStream)
		
		microphone.connect(analyser)
		
		// 测试音量检测
		const dataArray = new Uint8Array(analyser.frequencyBinCount)
		let maxVolume = 0
		let testCount = 0
		
		const testInterval = setInterval(() => {
			analyser.getByteFrequencyData(dataArray)
			const volume = dataArray.reduce((sum, value) => sum + value, 0) / dataArray.length
			maxVolume = Math.max(maxVolume, volume)
			testCount++
			
			if (testCount >= 20) { // 测试2秒
				clearInterval(testInterval)
				
				// 清理资源
				testStream.getTracks().forEach(track => track.stop())
				testAudioContext.close()
				
				if (maxVolume > 10) {
					alert(`✅ 麦克风测试成功！\n\n检测到音频输入，最大音量: ${maxVolume.toFixed(1)}%\n\n麦克风工作正常，可以开始录音。`)
				} else {
					alert(`⚠️ 麦克风测试完成\n\n检测到设备但音量较低 (${maxVolume.toFixed(1)}%)\n\n请检查：\n1. 麦克风是否静音\n2. 音量设置是否过低\n3. 是否对着麦克风说话`)
				}
			}
		}, 100)
		
	} catch (error) {
		console.error('麦克风测试失败:', error)
		
		let errorMessage = '❌ 麦克风测试失败\n\n'
		if (error.name === 'NotAllowedError') {
			errorMessage += '权限被拒绝\n\n请点击浏览器地址栏的麦克风图标，允许访问麦克风'
		} else if (error.name === 'NotFoundError') {
			errorMessage += '未找到麦克风设备\n\n请检查设备连接'
		} else if (error.name === 'NotReadableError') {
			errorMessage += '麦克风被占用\n\n请关闭其他使用麦克风的应用程序'
		} else {
			errorMessage += `错误: ${error.message}`
		}
		
		alert(errorMessage)
	}
}

// 播放录音
const playRecording = () => {
	if (!recordingPath.value) {
		alert('没有录音文件可播放')
		return
	}
	
	try {
		// 创建音频元素播放录音
		const audio = new Audio(recordingPath.value)
		audio.onplay = () => {
			isPlayingRecording.value = true
		}
		audio.onended = () => {
			isPlayingRecording.value = false
		}
		audio.onerror = (error) => {
			console.error('播放录音失败:', error)
			alert('播放录音失败，请检查文件是否损坏')
			isPlayingRecording.value = false
		}
		
		audio.play()
	} catch (error) {
		console.error('播放录音失败:', error)
		alert('播放录音失败: ' + error.message)
	}
}

// 停止播放录音
const stopPlayingRecording = () => {
	// 停止所有音频播放
	const audios = document.querySelectorAll('audio')
	audios.forEach(audio => {
		audio.pause()
		audio.currentTime = 0
	})
	
	isPlayingRecording.value = false
}

// 保存录音
const saveRecording = () => {
	if (!recordingPath.value) {
		alert('没有录音文件可保存')
		return
	}
	
	try {
		// 创建下载链接
		const link = document.createElement('a')
		link.href = recordingPath.value
		link.download = `录音_${new Date().getTime()}.webm`
		document.body.appendChild(link)
		link.click()
		document.body.removeChild(link)
		
		alert('录音文件已保存到下载文件夹')
	} catch (error) {
		console.error('保存录音失败:', error)
		alert('保存录音失败: ' + error.message)
	}
}

// 删除录音
const deleteRecording = () => {
	if (!recordingPath.value) {
		alert('没有录音文件可删除')
		return
	}
	
	if (confirm('确定要删除当前录音吗？')) {
		// 停止播放
		stopPlayingRecording()
		
		// 清理录音文件
		recordingPath.value = ''
		
		// 重置状态
		resetRecording()
		
		alert('录音已删除')
	}
}

// 清理资源
const cleanup = () => {
	stopTimer()
	stopPlayingRecording()
	if (audioContext.value) {
		audioContext.value.destroy()
		audioContext.value = null
	}
}


</script>

<style scoped>
.audio-recorder {
	padding: 20rpx;
	background: #f8f9fa;
	border-radius: 10rpx;
	margin: 20rpx 0;
}

.recorder-title {
	font-size: 32rpx;
	font-weight: bold;
	text-align: center;
	margin-bottom: 20rpx;
	color: #333;
}

.recorder-status {
	text-align: center;
	margin-bottom: 30rpx;
}

.status-indicator {
	padding: 10rpx 20rpx;
	border-radius: 20rpx;
	font-size: 28rpx;
	font-weight: bold;
	margin-bottom: 10rpx;
	display: inline-block;
}

.status-indicator.unsupported {
	background: #dc3545;
	color: white;
}

.status-indicator.initializing {
	background: #6c757d;
	color: white;
}

.status-indicator.ready {
	background: #e9ecef;
	color: #6c757d;
}

.status-indicator.recording {
	background: #dc3545;
	color: white;
	animation: pulse 1s infinite;
}

.status-indicator.paused {
	background: #ffc107;
	color: #212529;
}

.status-indicator.completed {
	background: #28a745;
	color: white;
}

.recording-time {
	font-size: 24rpx;
	color: #666;
}

.recorder-controls {
	display: flex;
	justify-content: space-around;
	margin-bottom: 30rpx;
}

.control-btn {
	padding: 15rpx 30rpx;
	border-radius: 8rpx;
	font-size: 26rpx;
	border: none;
	min-width: 120rpx;
}

.start-btn {
	background: #28a745;
	color: white;
}

.start-btn:disabled {
	background: #6c757d;
	color: #adb5bd;
}

.pause-btn {
	background: #ffc107;
	color: #212529;
}

.pause-btn:disabled {
	background: #6c757d;
	color: #adb5bd;
}

.stop-btn {
	background: #dc3545;
	color: white;
}

.stop-btn:disabled {
	background: #6c757d;
	color: #adb5bd;
}

.test-btn {
	background: #17a2b8;
	color: white;
}

.test-btn:hover {
	background: #138496;
}

.recording-info {
	background: white;
	padding: 20rpx;
	border-radius: 8rpx;
	margin-top: 20rpx;
}

.file-info {
	font-size: 24rpx;
	color: #666;
	margin-bottom: 15rpx;
	word-break: break-all;
}

.file-actions {
	display: flex;
	justify-content: space-around;
}

.action-btn {
	padding: 10rpx 20rpx;
	border-radius: 6rpx;
	font-size: 22rpx;
	border: none;
}

.play-btn {
	background: #007bff;
	color: white;
}

.save-btn {
	background: #28a745;
	color: white;
}

.delete-btn {
	background: #dc3545;
	color: white;
}

.recording-player {
	background: #e3f2fd;
	padding: 15rpx;
	border-radius: 8rpx;
	margin-top: 15rpx;
	text-align: center;
}

.player-info {
	font-size: 24rpx;
	color: #1976d2;
	margin-bottom: 10rpx;
}

.compatibility-warning {
	background: #f8d7da;
	color: #721c24;
	padding: 15rpx;
	border-radius: 8rpx;
	text-align: center;
	font-size: 24rpx;
	margin-top: 20rpx;
}

@keyframes pulse {
	0% { opacity: 1; }
	50% { opacity: 0.5; }
	100% { opacity: 1; }
}
</style>
